https://blog.boot.dev/golang/anonymous-structs-golang/
I often use anonymous structs to marshal and unmarshal JSON data in HTTP handlers. If a struct is only meant to be used once, then it makes sense to declare it in such a way that developers down the road won’t be tempted to accidentally use it again.
Take a look at the code below. We are able to marshal the HTTP request directly into an unnamed struct inline. All the fields are still accessible via the dot operator, but we don’t have to worry about another part of our project trying to use a type that wasn’t intended for it.
func createCarHandler(w http.ResponseWriter, req *http.Request) {
defer req.Body.Close()
decoder := json.NewDecoder(req.Body)
newCar := struct {
Make string `json:"make"`
Model string `json:"model"`
Mileage int `json:"mileage"`
}{}
err := decoder.Decode(&newCar)
if err != nil {
log.Println(err)
return
}
makeCar(newCar.Make, newCar.Model, newCar.Mileage)
return
}Instead of declaring a quick anonymous struct for JSON unmarshalling, I’ve often seen map[string]interface{} used. This is *terrible *in most scenarios for several reasons:
- No type checking. If the client sends a key called “name” with a
boolvalue, but your code is expecting astring, then unmarshalling into a map won’t catch the error - Maps are vague. After unmarshalling the data, we are forced to use runtime checks to make sure the data we care about exists. If those checks aren’t thorough, it can lead to a nil pointer dereference panic being thrown.
**map[string]interface{}**** is verbose**. Digging into the map isn’t as simple as accessing a named field using a dot operator, for example,newCar.model. Instead, it is something like: